package net.bezrabotnih.server.domain;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.FetchType;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Query;
import javax.persistence.Transient;
import javax.validation.constraints.NotNull;
import org.springframework.roo.addon.entity.RooEntity;
import org.springframework.roo.addon.javabean.RooJavaBean;
import org.springframework.roo.addon.tostring.RooToString;

@RooJavaBean
@RooToString
@RooEntity(identifierType = String.class, identifierField = "id", finders = { "findJobsByProviderIdEquals" })
public class Job {

    public static int NEW = 0;

    public static int DONE = 1;

    @NotNull
    private String jobTypeId;
    
    @Transient
	private JobType jobType; 

    @NotNull
    private Boolean isHourly;

    @NotNull
    private String name;

    private String description;

    @NotNull
    private Integer price;

    @NotNull
    private Integer status;

    private Date startDate;

    private Date deadLine;

    @NotNull
    private String providerId;
//
    @Transient
    private List<String> applicantIds;

    private String winnerId;
    
    @Transient
    private UserAccount winner;

    private List<String> commentIds;
    
    private Date created=new Date();
    
    public UserAccount getWinner(){
    	if (winner==null&&winnerId!=null){
    		winner=UserAccount.findUserAccount(winnerId);
    	}
    	return winner;
    }
    
    
    public List<String> getApplicantIds(){
    	
         if (applicantIds==null){
        	 List<Application> applications=Application.findApplicationsByJobId(this.getId());
        	 applicantIds=new ArrayList<String>();
        	 for (Application application:applications) applicantIds.add(application.getUserAccountId());
         }
         
         return applicantIds;
    	
    }
    
    
  


	public JobType getJobType() {
        JobType jobType=null;
    	if (this.jobTypeId != null) {
            if (jobType == null || jobType.getId() != this.jobTypeId) {
                jobType = JobType.findJobType(this.jobTypeId);
            }
        } else {
            jobType = null;
        }
        return jobType;
    }
    
    
//    public void setJobType(JobType jobType) {
//        if (jobType != null) {
//            if (jobType.getId () == null) {
//            	jobType.persist();
//            }
//            this.jobTypeId = jobType.getId();
//        } else {
//            this.jobTypeId = null;
//        }
//        this.jobType = jobType;
//    }
    
    
    
    
    @SuppressWarnings("unchecked")
	public static List<Job> findJobsByProviderId(String providerId){
    	return findJobsByProviderIdEquals(providerId).getResultList();    	
    	
    }
    
    @SuppressWarnings("unchecked")
	public static List<Job> findAvailableJobsByPerformerId(String performerId){
    	 if (performerId == null || performerId.length() == 0) throw new IllegalArgumentException("The providerId argument is required");
         UserAccount userAccount=UserAccount.findUserAccount(performerId);
    	 EntityManager em = Job.entityManager();
    	 if (userAccount==null||userAccount.getJobTypeIds()==null||userAccount.getJobTypeIds().size()==0) return null;
         Query q = em.createQuery("SELECT o FROM Job AS o WHERE o.jobTypeId MEMBER OF  :jobTypeIds AND o.winnerId =:winnerId AND o.status =:status");
         q.setParameter("jobTypeIds", userAccount.getJobTypeIds()).setParameter("winnerId", null).setParameter("status", Job.NEW);
         return q.getResultList();
    	
    }
    
    @SuppressWarnings("unchecked")
	public static List<Job> findJobsByWinnerId(String winnerId){
    	 if (winnerId == null || winnerId.length() == 0) throw new IllegalArgumentException("The providerId argument is required");
    	 EntityManager em = Job.entityManager();
         Query q = em.createQuery("SELECT o FROM Job AS o WHERE o.winnerId =:winnerId");
         q.setParameter("winnerId", winnerId);
         return q.getResultList();
    	
    }
    
    @SuppressWarnings("unchecked")
	public static List<Job> findJobsByProviderIdWithWinnerNull(String providerId){
    	 if (providerId == null || providerId.length() == 0) throw new IllegalArgumentException("The providerId argument is required");
    	 EntityManager em = Job.entityManager();
         Query q = em.createQuery("SELECT o FROM Job AS o WHERE o.providerId =:providerId AND o.winnerId=:winnerId");
         q.setParameter("providerId", providerId).setParameter("winnerId", null);
         return q.getResultList();
    	
    }
    
    
    @SuppressWarnings("unchecked")
	public static List<Job> findDoneJobsByProviderId(String providerId){
    	
    	 if (providerId == null || providerId.length() == 0) throw new IllegalArgumentException("The providerId argument is required");
    	 EntityManager em = Job.entityManager();
         Query q = em.createQuery("SELECT o FROM Job AS o WHERE o.providerId =:providerId AND o.deadLine<=:now");
         q.setParameter("providerId", providerId).setParameter("now", new Date());
         List<Job> jobs=q.getResultList();
         for (Job job:jobs){
        	 if (job.getWinner()==null) jobs.remove(job);
         }
         return jobs;
    	
    	
    }
    
    public Date getCreated() {
  		return created;
  	}


  	public void setCreated(Date created) {
  		this.created = created;
  	}


  	public List<String> getCommentIds() {
  		return commentIds;
  	}


  	public void setCommentIds(List<String> commentIds) {
  		this.commentIds = commentIds;
  	}
    
    
    
}
